package com.sunny.search.api.service;

import com.alibaba.fastjson.JSONObject;
import com.sunny.elasticsearch.ElasticsearchHandler;
import com.sunny.redis.JedisHandler;
import com.sunny.search.model.pojo.common.AggregationInfo;
import com.sunny.search.model.pojo.common.HighlightInfo;
import com.sunny.search.model.pojo.common.SortInfo;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilder;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.ParsedTerms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.FieldSortBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * service基类
 * @author fengxiangyang
 * @date 2018/12/5
 */
public class BaseService {
    private static final Logger logger = LoggerFactory.getLogger(BaseService.class);
    @Autowired
    protected ElasticsearchHandler elasticsearchHandler;
    @Autowired
    protected JedisHandler jedisHandler;
    /**
     * 排序
     *
     * @return
     */
    protected List<SortBuilder<?>> baseSortBuilder(List<SortInfo> sortInfoList) {
        List<SortBuilder<?>> list = new ArrayList<>();
        if (CollectionUtils.isEmpty(sortInfoList)) {
            list.add(SortBuilders.scoreSort());
        } else {
            sortInfoList.sort(Comparator.comparing(SortInfo::getSequence));
            for (SortInfo query : sortInfoList) {
                SortOrder sortOrder = SortInfo.Order.ASC.equals(query.getOrder()) ? SortOrder.ASC : SortOrder.DESC;
                final FieldSortBuilder fieldSortBuilder = SortBuilders.fieldSort(query.getField()).order(sortOrder);
                list.add(fieldSortBuilder);
            }
        }
        return list;
    }

    /**
     * 高亮
     * @return
     */
    protected HighlightBuilder baseHighlightBuilder(HighlightInfo highlightInfo){
        if(highlightInfo != null){
            final List<String> fields = highlightInfo.getFields();
            if(fields != null && !fields.isEmpty()){
                HighlightBuilder highlightBuilder = new HighlightBuilder();
                fields.forEach(o-> highlightBuilder.field(new HighlightBuilder.Field(o)));
                final String preTag = highlightInfo.getPreTag();
                if(!StringUtils.isEmpty(preTag)){
                    highlightBuilder.preTags(preTag);
                }
                final String postTag = highlightInfo.getPostTag();
                if(!StringUtils.isEmpty(postTag)){
                    highlightBuilder.postTags(postTag);
                }
                return highlightBuilder;
            }
        }
        return null;
    }

    /**
     * 聚合查询
     * @return
     */
    protected List<AggregationBuilder> baseAggregationBuilders(List<AggregationInfo> aggregationInfoList) {
        if (CollectionUtils.isEmpty(aggregationInfoList)) {
            return null;
        }
        List<AggregationBuilder> list = new ArrayList<>();
        for (AggregationInfo query : aggregationInfoList) {
            final TermsAggregationBuilder builder = AggregationBuilders.terms(query.getName()).field(query.getField()).size(query.getSize());
            list.add(builder);
        }
        return list;
    }

    /**
     * 聚合结果
     * @return
     */
    protected Map<String,Collection<?>> getAggregationVO(Aggregations aggregations, List<AggregationInfo> aggregationInfoList){
        if(CollectionUtils.isEmpty(aggregationInfoList) || aggregations == null){
            return null;
        }
        final Map<String, Aggregation> aggregationMap = aggregations.asMap();
        Map<String,Collection<?>> map = new HashMap<>();
        for (AggregationInfo aggregationInfo : aggregationInfoList) {
            final ParsedTerms parsedTerms = (ParsedTerms)aggregationMap.get(aggregationInfo.getName());
            List<String> bucketList = new ArrayList<>();
            parsedTerms.getBuckets().forEach(o -> bucketList.add(o.getKeyAsString()));
            map.put(aggregationInfo.getName(),bucketList);
        }
        return map;
    }

    /**
     * 处理高亮信息并返回JSON
     * @param searchHit
     * @param highlightInfo
     * @return json
     */
    public JSONObject getHitJSONObject(SearchHit searchHit, HighlightInfo highlightInfo) {
        final JSONObject jsonObject = JSONObject.parseObject(searchHit.getSourceAsString());
        jsonObject.put("id",searchHit.getId());
        if(highlightInfo != null){
            final Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
            final List<String> fields = highlightInfo.getFields();
            for (String field : fields) {
                final HighlightField highlightField = highlightFields.get(field);
                if(highlightField != null){
                    final Text[] fragments = highlightField.getFragments();
                    jsonObject.put(field,fragments[0].string());
                }
            }
        }
        return jsonObject;
    }

}